Skip to content

BREAKING: Check Raw identifiers' types and drop malformed values - #65

Open
jrosendahl-opt wants to merge 3 commits into
masterfrom
feat/raw-identifier-checks
Open

jrosendahl-opt wants to merge 3 commits into
masterfrom
feat/raw-identifier-checks

Conversation

@jrosendahl-opt

@jrosendahl-opt jrosendahl-opt commented Nov 10, 2026 •

Copy link
Copy Markdown
Contributor

Why

OptableIdentifier.Raw sent any string unchanged, so Raw("e:jane@example.com") sent a plaintext Email and malformed values went to the DCN as-is. The iOS SDK checks raw identifiers (optable-ios-sdk#98), and the same strict behaviour was requested for both SDKs.

What Changed

  • android_sdk: behaviour change Raw("type:value"), split on the first ::
    • A known type (e, p, z, i4, i6, a, g, r, s, f, n, id5, utiq, v, c / c<number>) is encoded exactly like its typed identifier. e and p map to Hem / HashedPhoneNumber, so a value that isn't a SHA-256 hash is dropped. c0 is sent as c, a negative number uses its absolute value. g gets the same dedupe against the device GAID as GoogleGaid.
    • An unknown type is sent as given (xyz:Some Value, xyz:a:b, cookie:abc). Types are case-sensitive.
    • No :, an empty or whitespace-only type (:abc, :abc), an empty or whitespace-only value (xyz:, xyz: ), or an empty string is dropped, from identify and from targeting ids and hids alike.
  • android_sdk: IdentifiersEncoder encodes one identifier in its own function so a known raw value goes through the same code as its typed identifier.
  • android_sdk tests: known types, custom types, plaintext vs hashed e/p, unknown types, malformed values, raw g dedupe.

tryIdentifyFromUrl() already checks the hash before sending Raw("e:<hash>"), so it keeps working.

How to Test

  • ./gradlew test passes (166 tests locally)
  • Verified in DemoAppJava / DemoAppKotlin (the demos don't use Raw)
  • README updated (if public API changed): the KDoc is updated; Document undocumented SDK behaviour in the README #60's identifier table needs its Raw row updated

Notes

Do not merge before v1.3.0 is tagged. For 2.0.0, alongside #63. Apps passing plaintext or malformed values through Raw silently stop sending them; code still compiles.

Rebase needed against whichever merge first: #62 (encode() takes the GAID as a parameter) and #63 (Custom(index, value) and OptableVID, which this code should then build for c / cN and v).

  • Breaking change
  • Requires release

🤖 Generated with Claude Code

OptableIdentifier.Raw sent any string unchanged. Match the iOS SDK
(optable-ios-sdk#98):

- A known type is encoded exactly like its typed identifier. "e" and
  "p" must already be SHA-256 hashes, like Hem and HashedPhoneNumber,
  or the ID is dropped, so Raw("e:jane@example.com") never sends a
  plaintext Email. Custom types are "c" and "c<number>".
- An unknown type is sent as given, split on the first ":".
- A value with no ":", an empty type or an empty value is dropped.

Apps passing plaintext or malformed values through Raw stop sending
them, so this is for 2.0.0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@jrosendahl-opt
jrosendahl-opt requested review from a team as code owners November 10, 2026 02:11
@jrosendahl-opt jrosendahl-opt mentioned this pull request Nov 10, 2026
2 of 5 tasks
jrosendahl-opt and others added 2 commits November 9, 2026 19:24
Treat a whitespace-only value like an empty one, so "xyz:   " is dropped
instead of being sent, matching the iOS follow-up to optable-ios-sdk#98.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Treat a whitespace-only type like an empty one, so "  :abc" is dropped,
matching optable-ios-sdk#98.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant